delete可以幫助我們刪除所有的object。其用法和select非常相近,而事實上delete其實是delete (select ...)的語法糖。
我們繼續使用[Day03]中定義的schema:
type User {
required name: str;
multi followers: User;
}
type Article {
required title: str;
required author: User;
}
執行下列query生成兩個Article object及四個User object。
insert Article {
title:= "first article",
author:= (insert User {name:= "John"})
};
insert Article {
title:= "second article",
author:= (insert User {name:= "Jeff"})
};
for name in {"Tom", "Cathy"}
union (insert User {name:= name});
以下我將以Cathy、John、Tom與Jeff來簡單稱呼其name property分別為「"Cathy"」、「"John"」、「"Tom"」與「"Jeff"」的User object。
假設現在我們想刪除tom,可以這麼寫:
delete User filter .name="Tom";
但delete是一個很重要的操作,通常會先使用select來確認所選到object是否符合:
select User filter .name="Tom";
確認選擇無誤後,再將select換成delete。
如果是面對比較複雜的query時,會建議在with中建立中間變數,像是:
with tom:= (select User filter .name="Tom")
select tom {name};
確認選擇無誤後,再將select換成delete:
with tom:= (select User filter .name="Tom")
delete tom {name};
如果我們想要刪掉所有的object,您可能會很直覺的想要使用for-loop。但別忘了,delete是delete (select ...)的語法糖,所以回想一下我們是怎麼使用select選擇object的呢?沒錯,直接select就好,所以bulk delete最快的方法是,使用select確認選擇無誤:
select User;
select Article;
再將select換成delete:
delete User;
delete Article;
delete是一個頗為複雜的主題,有可能需要針對每一個object type,制訂不同的deletion police。Easy EdgeDB第十三章中有提到一些可能遇到的複雜情況。
deletion police可以分為target deletion及source deletion兩種。
其中target deletion有:
restrict(預設)。delete source。allow。deferred restrict。而source deletion有:
allow。delete target。delete target if orphan。我們這邊舉幾個常用的情況供大家參考。
由於on target delete restrict是預設,所以目前User object的schema與下面的schema其實是相同的:
type User {
required name: str;
multi followers: User {
on target delete restrict;
};
}
這個deletion police是指當有一個User object連接到其它User object的multi followers link時,這個User object是無法被刪除的。
舉例來說,如果我們將John與Tom指定為Jeff的multi followers link:
with jeff:= (select User filter .name="Jeff"),
followers:= (select User filter .name in {"John", "Tom"})
update jeff
set {
followers:= followers
};
假設此時我們試圖delete John:
delete User filter .name="John";
會報錯如下:
edgedb error: ConstraintViolationError: deletion of default::User (988d4658-5248-11ef-af3f-b785e4ec0502) is prohibited by link target policy
Detail: Object is still referenced in link followers of default::User (988d46d0-5248-11ef-af3f-57711cc00e48).
因為John仍在Jeff的multi followers link中。
此時如果將delete policy改為on target delete delete source:
type User {
required name: str;
multi followers: User {
on target delete delete source;
};
}
這個deletion police是指當有一個User object連接到其它User object的multi followers link時,如果這個User object被刪除的話,與其連接的User object也會被刪除。
此時我們可以刪除John:
delete User filter .name="John";
再確認剩下哪些User object:
select User {name, followers};
{
default::User {
name: 'Cathy',
followers: {}
},
default::User {
name: 'Tom',
followers: {}
}
}
可以發現只剩下Cathy及Tom。這是因為當我們刪除John(target)時,也會刪除Jeff(source)。
接著我們將delete policy改為on source delete delete target:
type User {
required name: str;
multi followers: User {
on source delete delete target;
};
}
並重新insert回John跟Jeff:
for name in {"John", Jeff"}
union (insert User {name:= name});
並將John與Tom指定為Jeff的multi followers link:
with jeff:= (select User filter .name="Jeff"),
followers:= (select User filter .name in {"John", "Tom"})
update jeff
set {
followers:= followers
};
這個deletion police是指當有一個User object被刪除時,與其multi followers link所連接的User object也會被刪除。
此時我們可以刪除Jeff:
delete User filter .name="Jeff";
再確認剩下哪些User object:
select User {name, followers};
{default::User {name: 'Cathy', followers: {}}}
可以發現只剩下Cathy。這是因為當我們刪除Jeff(source)時,也會刪除John及Tom(target)。